import heapq
from copy import deepcopy
from typing import Tuple, Optional, Union, List

from model.transition import Transition


class TransitionsQueue:
    def __init__(self) -> None:
        self._pq = []

    def __str__(self) -> str:
        if not self._pq: return "TransitionsQueue: None"
        else:
            pq = deepcopy(self._pq)
            s = "TransitionsQueue: \n"
            while pq:
                transition = heapq.heappop(pq)
                s += ("Time: " + str(transition[0]) + " | Component: " + str(transition[1]) +
                      " | Transition: \n" + str(transition[2]) + "\n" )
            return s

    def empty(self) -> bool:
        return not self._pq

    def put_transitions(self, component_transition: Tuple[float, Union[str, Tuple[str, str]], Transition]):
        # self.put_nowait(component_transition)
        heapq.heappush(self._pq, component_transition)

    def get_transitions(self) -> Optional[Tuple[float, Union[str, Tuple[str, str]], Transition]]:
        if not self._pq:
            return None
        else:
            return heapq.heappop(self._pq)

    def time_stamp(self) -> List[float]:
        return [item[0] for item in self._pq]

if __name__ == "__main__":
    tq = TransitionsQueue()
    print(tq.get_transitions())
    from state import State
    from action import Action
    from delay import Delay
    edge_name = "n1"
    s0 = State("up", True, {"a", "b"})
    s1 = State("down", False, {"a", "b"})
    t1 = Transition(s0, s1, "fail", Delay("exp", 2), 1,
                    Action(edge_name, "fail", "active"), None, None, None)
    t2 = Transition(s1, s0, "repair", Delay("exp", 1), 1,
                    Action(edge_name, "repair", "active"), None, None, None)
    tq.put_transitions((2, "n1", t1))
    tq.put_transitions((3, "n1", t1))
    tq.put_transitions((3, "n1", t1))
    tq.put_transitions((6, "n1", t1))
    tq.put_transitions((0, "n1", t2))
    print(tq)
    print(tq.get_transitions())
    # (0, 'n1', < transition.Transition object at 0x0000015C4569D760 >)
    print(tq.time_stamp())
    # for t in tq:
    #     print(t)